# LeetCode 1、两数之和

# 一、题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

# 二、题目解析

# 三、参考代码

# 1、Java 代码

// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 两数之和(LeetCode 1):https://leetcode-cn.com/problems/two-sum/
class Solution {
    public int[] twoSum(int[] nums, int target) {

        // 首先构建一个哈希表,用来存放数组的元素值以及索引值
        // 其中 key 是数组中的元素值
        // value 为数组中元素值的索引
        Map<Integer,Integer> map = new HashMap<>();

        // 接下来,遍历整个数组
        for(int i = 0; i < nums.length; i++) {

            // 目标值为 target,将 target 与 nums[i] 求差
            // 获取与 nums[i] 配对的那个数 anotherNum
            int anotherNum = target - nums[i];

            // 判断哈希表中是否存在那个与 nums[i] 配对的数 anotherNum
            if (map.containsKey(anotherNum)) {

                // 由于哈希表中所有 key 都是来自于数组中,
                // 所以,如果发现哈希表存在那个与 nums[i] 配对的数 anotherNum
                // 也就说明数组中存在一个数,可以和 nums[i] 相加为 target
                // 此时, anotherNum 这个 key 对应的 value 为这个数在数组中的索引
                // 所以,返回 map.get(anotherNum) 和 i 就是这两个值的下标
                return new int[]{map.get(anotherNum), i};
            }else{
               // 如果发现哈希表中目前不存在那个与 nums[i] 配对的数 anotherNum
               // 那么就把此时观察的数 nums[i] 和它的索引存放到哈希表中
               // 等待后面的数能和它配对为 target
               map.put(nums[i], i);
            }

        }

        // 如果遍历完整个数组都找不到和为 target 的两个数,返回 0
        return new int[0];
    }
}

# **2、**C++ 代码

// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 两数之和(LeetCode 1):https://leetcode-cn.com/problems/two-sum/
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        // 首先构建一个哈希表,用来存放数组的元素值以及索引值
        // 其中 key 是数组中的元素值
        // value 为数组中元素值的索引
        unordered_map< int , int > map;

        // 接下来,遍历整个数组
        for(int i = 0; i < nums.size(); i++) {

            // 目标值为 target,将 target 与 nums[i] 求差
            // 获取与 nums[i] 配对的那个数 anotherNum
            int anotherNum = target - nums[i];

            // 判断哈希表中是否存在那个与 nums[i] 配对的数 anotherNum
            auto it = map.find(anotherNum);
            if (it != map.end()) {
                // 由于哈希表中所有 key 都是来自于数组中,
                // 所以,如果发现哈希表存在那个与 nums[i] 配对的数 anotherNum
                // 也就说明数组中存在一个数,可以和 nums[i] 相加为 target
                // 此时, anotherNum 这个 key 对应的 value 为这个数在数组中的索引
                // 所以,返回 map.get(anotherNum) 和 i 就是这两个值的下标
                return {map[anotherNum], i};
            }else{
               // 如果发现哈希表中目前不存在那个与 nums[i] 配对的数 anotherNum
               // 那么就把此时观察的数 nums[i] 和它的索引存放到哈希表中
               // 等待后面的数能和它配对为 target
               map[nums[i]] =  i;
            }

        }

        // 如果遍历完整个数组都找不到和为 target 的两个数,返回 0
        return {};
    }
};

# 3、Python 代码

# 登录 AlgoMooc 官网获取更多算法图解
# https://www.algomooc.com
# 作者:程序员吴师兄
# 代码有看不懂的地方一定要私聊咨询吴师兄呀
# 两数之和(LeetCode 1):https://leetcode-cn.com/problems/two-sum/
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
       # 首先构建一个哈希表,用来存放数组的元素值以及索引值
       # 其中 key 是数组中的元素值
       # value 为数组中元素值的索引
       map = dict()

       # 接下来,遍历整个数组
       for i, num in enumerate(nums):
           # 目标值为 target,将 target 与 nums[i] 求差
           # 获取与 nums[i] 配对的那个数 anotherNum
           anotherNum = target - num

           # 判断哈希表中是否存在那个与 nums[i] 配对的数 anotherNum
           if anotherNum in map :

               # 由于哈希表中所有 key 都是来自于数组中,
               # 所以,如果发现哈希表存在那个与 nums[i] 配对的数 anotherNum
               # 也就说明数组中存在一个数,可以和 nums[i] 相加为 target
               # 此时, anotherNum 这个 key 对应的 value 为这个数在数组中的索引
               # 所以,返回 map.get(anotherNum) 和 i 就是这两个值的下标
               return [ map[ target - num ] , i ]
           else:
              # 如果发现哈希表中目前不存在那个与 nums[i] 配对的数 anotherNum
              # 那么就把此时观察的数 nums[i] 和它的索引存放到哈希表中
              # 等待后面的数能和它配对为 target
             map[nums[i]] = i

       # 如果遍历完整个数组都找不到和为 target 的两个数,返回 0
       return []

# 四、复杂度分析

时间复杂度:O(N),其中 N 是数组中的元素数量。对于每一个元素 x,我们可以 O(1) 地寻找 target - x。

空间复杂度:O(N),其中 N 是数组中的元素数量。主要为哈希表的开销。